"""
    * 编码设置：decode_responses=True确保返回字符串而非字节类型
    * 连接池：高并发场景需使用连接池管理连接
    * 事务：使用WATCH机制实现乐观锁，避免竞态条件
    * 超时设置：通过socket_timeout参数设置连接超时
    * 数据类型：根据业务场景选择合适的数据结构（如缓存用 String，排行榜用 Sorted Set）
"""
import redis

r = redis.Redis(
    host='localhost',
    port=6379,
    password=None,
    db=0,
    decode_responses=True # 返回字符串非字节
)

try:
    r.ping()
    print("Connected to Redis server~")
except redis.exceptions.ConnectionError as e:
    print(f"Error connecting to Redis: {e}")


r.set('name', 'Alice')
print(r.get('name')) # 输出: Alice

r.set('counter', 10)
r.incr('counter')
print(r.get('counter')) # 输出11


print('\n==================哈希操作==================\n')

r.hset('user:1', 'name', 'Bob')
r.hset('user:1', 'age', 30)
print(r.hget('user:1','age')) #输出：30

print(r.hgetall('user:1')) # 输出: {'name':'Bob', 'age': '30'}


print('\n====================列表操作========================\n')
r.lpush('tasks','task1')
r.lpush('tasks','task2')

print(r.lrange('tasks', 0, -1)) # 输出: ['task2', 'task1']

# 从右侧弹出元素
print(r.rpop('tasks')) # 输出：task1


print('\n==================集合操作====================\n')
r.sadd('fruits', 'apple')
r.sadd('fruits', 'banana')
r.sadd('fruits', 'orange')

print(r.smembers('fruits')) # 输出： {'apple', 'banana'}

print('\n====================有序集合操作====================\n')
r.zadd('scores', {'Alice':95, 'Bob': 85, 'Charlie': 90})
print(r.zrangebyscore('scores', 80, 90)) # 输出: ['Bob', 'Charlie']

print('\n====================事务操作====================\n')
r.set('balance', 12)
with r.pipeline() as pipe:
    while True:
        try:
            # 监听键变化
            pipe.watch('balance')
            balance = int(pipe.get('balance'))

            if balance < 10:
                pipe.unwatch()
                print("余额不足")
                break

            # 开始事务
            pipe.multi()
            pipe.decrby('balance', 10)
            pipe.incrby('expenses', 10)
            pipe.execute()
            print("交易成功")
            break
        except redis.WatchError:
            # 重试
            continue

print('\n====================连接池管理====================\n')
# 创建连接池
pool = redis.ConnectionPool(
    host='localhost',
    port=6379,
    max_connections=10,
    decode_responses=True # 返回字符串非字节
)

# 使用连接池创建客户端
r = redis.Redis(connection_pool=pool)
r.set('connect_method', 'Connection_Pool')
print(r.get('connect_method'))

"""
    一、架构层面：应对高并发与高可用
    集群部署（Cluster）
    使用 Redis Cluster 实现数据分片（Sharding），将数据分布到多节点，解决单节点内存限制和性能瓶颈。
    典型场景：亿级用户缓存、分布式计数器、秒杀系统库存扣减等。
    哨兵模式（Sentinel）
    自动监控主节点故障，实现主从切换，保障服务高可用性。
    结合配置中心（如 Apollo）动态更新客户端连接信息。
    混合存储架构
    热数据（高频访问）存 Redis，冷数据（低频访问）存数据库或分布式存储（如 HBase），通过 TTL 或 LRU 策略淘汰冷数据。
    案例：电商商品详情页（热数据）+ 历史订单（冷数据）。
    
    二、高级数据结构与业务场景
    Stream：分布式消息队列
    替代 Kafka/RabbitMQ 实现轻量级消息队列，支持消息持久化、消费者组（Consumer Group）、有序消息流等。
    场景：实时日志采集、异步任务队列、用户行为追踪。
    布隆过滤器（Bloom Filter）
    用 BF.ADD/BF.EXISTS 指令实现缓存穿透防护，判断数据是否存在于 Redis（概率性数据结构，适合去重或防刷）。
    案例：防止恶意请求击穿缓存（如查询不存在的用户 ID）。
    HyperLogLog：基数统计
    用 PFADD/PFCOUNT 统计独立元素数量（如日活用户数），内存占用极低（每个 HyperLogLog 仅需 12KB 内存）。
    注意：结果是近似值，适合允许误差的场景（如统计 PV/UV）。
    Geospatial：地理信息处理
    用 GEOADD/GEODIST 实现附近的人、骑手接单范围等功能（基于经纬度计算距离）。
    案例：外卖平台骑手调度、社交 APP 附近用户推荐。
    
    三、性能优化与工程实践
    Pipeline 批量操作
    一次性发送多条命令到 Redis，减少网络往返开销（适用于批量写入 / 查询，如批量更新缓存）。
    python
    with r.pipeline(transaction=False) as pipe:
        pipe.set('key1', 'value1')
        pipe.set('key2', 'value2')
        pipe.execute()
    
    LUA 脚本原子性操作
    用 EVAL 执行自定义 LUA 脚本，确保复杂逻辑的原子性（如库存扣减 + 积分增加）。
    避免多次网络交互导致的竞态条件。
    热 Key 与大 Key 治理
    热 Key：单个 Key 被高频访问，导致单节点压力过大。
    解决方案：本地缓存（如 Caffeine）+ 定期刷新、主从复制多读、拆分成子 Key。
    大 Key：单个 Key 存储数据过大（如超过 1MB），导致网络传输慢、内存碎片化。
    解决方案：拆分成多个子 Key（如 user:1:info、user:1:order）、使用 Hash 结构替代 String。
    缓存预热与懒加载
    预热：启动时提前加载热点数据到 Redis（如通过定时任务或消息队列）。
    懒加载：首次访问时加载数据到缓存，结合 TTL 避免冷数据长期占用内存。
    
    四、分布式系统中的关键应用
    分布式锁（RedLock）
    使用 Redis 实现跨服务的互斥锁（需保证分布式环境下的原子性），常见方案：
    单节点锁：SET key value NX PX 30000（简单但主节点故障可能导致锁丢失）。
    RedLock 算法：基于多个独立 Redis 实例实现强一致性锁（适用于微服务架构）。
    python
    # 示例：单节点分布式锁
    import time
    lock_key = "resource:lock"
    identifier = str(time.time())  # 唯一标识防止误删
    acquired = r.set(lock_key, identifier, nx=True, px=5000)
    if acquired:
        try:
            # 执行业务逻辑
        finally:
            # 释放锁（需验证标识，避免误删其他线程的锁）
            r.eval("if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end",
                   1, lock_key, identifier)
    
    分布式会话（Session Sharing）
    将用户会话存储在 Redis 中，解决微服务架构下的会话共享问题（如 JWT + Redis 存储用户权限信息）。
    限流与计数器
    用 INCR + EXPIRE 实现滑动窗口或令牌桶限流（如限制用户每分钟最多请求 100 次）。
    案例：防止恶意刷接口、控制接口调用频率。
    
    五、监控与运维
    核心指标监控
    使用 INFO 命令监控内存使用（used_memory）、命中率（keyspace_hits/keyspace_misses）、连接数（connected_clients）、慢查询（slowlog）等。
    集成 Prometheus + Grafana 实现可视化监控，设置告警规则（如内存使用率超过 80% 触发扩容）。
    数据持久化策略
    RDB：定时快照（适合大规模数据备份，但可能丢失最近写入的数据）。
    AOF：日志追加（数据安全性更高，支持每秒同步或实时同步）。
    大厂通常混合使用 RDB + AOF，并定期进行全量备份和增量备份。
    内存优化与碎片整理
    合理设置 maxmemory-policy（如 allkeys-lru），淘汰冷数据。
    定期执行 BGREWRITEAOF 或 RECOMPILE 清理内存碎片（INFO memory 查看 mem_fragmentation_ratio）。
    
    六、安全与合规
    访问控制
    禁用公网访问，通过 VPC 或内网防火墙限制 Redis 节点访问。
    设置强密码，启用 requirepass 认证，禁止使用默认端口（6379）。
    数据加密
    传输层加密：使用 TLS/SSL（Redis 6.0+ 原生支持 tls-cert-file 等配置）。
    数据加密：对敏感数据（如用户密码）在写入 Redis 前进行加密（如 AES 算法）。
    审计与合规
    记录 Redis 操作日志，对接公司审计系统（如通过 Proxy 层拦截命令并日志脱敏）。
    总结：大厂 Redis 的核心定位
    在大厂中，Redis 不仅是 “缓存”，更是分布式系统的基础设施，承担着缓存、消息队列、分布式锁、计数器、地理信息处理等多重角色。其核心挑战在于：
    性能：应对亿级流量下的读写性能瓶颈（通过集群、Pipeline、LUA 优化）。
    稳定性：避免缓存雪崩 / 穿透 / 击穿，保障高可用性（通过哨兵、集群、布隆过滤器）。
    成本：优化内存使用，平衡性能与成本（冷热数据分离、大 Key 治理）。
    扩展性：支持业务快速迭代，灵活适配新场景（如 Stream 消息队列、Search 全文搜索）。
"""